/**
 * @Author       : Mo 2427995270@qq.com
 * @Date         : 2025-04-24 11:13:53
 * @LastEditTime : 2025-06-13 10:49:44
 * @FilePath     : \GD32F407_BL\mobl\hal_driver\ll_uart.c
 * @Description  : uart低层驱动
 * @Version      : V1.0
 * @History      :
 * @Note         : 目前不支持同步模式，仅支持8bit 无奇偶校验。8bit开启奇偶校验 数据位仅7位可用，9bit开启奇偶校验 数据位有8位，不开启有9位
 */
/***************************************Includes***********************************/
#include "ll_uart.h"
#include "ll_gpio.h"
#include "os_config.h"
// clang-format off
#if defined(GD32F407)
    #include "gd32f4xx.h"
#elif defined(GD32F10X_HD)
    #include "gd32f10x.h"
#elif defined(STM32F10X_HD)
    #include "stm32f10x.h"
#elif defined(STM32F40_41xxx)
    #include "stm32f4xx.h"
#elif defined(PY32F071xB)
    #include "py32f0xx.h"
#else
    #error "No device selected"
#endif
// clang-format on

/************************************Private Macros********************************/
#if defined(GD32F407)
#define UART_QUANTITY 6
#elif defined(GD32F10X_HD)
#define UART_QUANTITY 5
#elif defined(STM32F10X_HD)
#define UART_QUANTITY 5
#elif defined(STM32F40_41xxx)
#define UART_QUANTITY 6
#elif defined(PY32F071xB)
#define UART_QUANTITY 4
#else
#error "No device selected"
#endif


/**********************************Private Statement*******************************/
static int gd32_uart_init(uart_ll_t *uct);
static int stm32_uart_init(uart_ll_t *uct);
static int py32_uart_init(uart_ll_t *uct);

/***********************************Public Variables*******************************/



/**********************************Private Variables*******************************/

static uart_ll_t *uart_handle[UART_QUANTITY];

/**********************************Public Functions********************************/

/**
 * @brief 初始化uart
 * @param  uct
 * @param  rx_cb            接收回调
 * @param  arg              用户参数
 * @return int 0成功 -1失败
 * @note null
 */
int uart_ll_init(uart_ll_t *uct, uart_ll_rx_interrupt_cb_t rx_cb, void *arg) {
    uct->rx_cb = rx_cb;
#if defined(GD32F407) || defined(GD32F10X_HD)
    return gd32_uart_init(uct);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    return stm32_uart_init(uct);
#elif defined(PY32F071xB)
    return py32_uart_init(uct);
#endif
}
/**
 * @brief 反初始化uart
 * @param  uct
 * @return int 0成功 -1失败
 * @note null
 */
int uart_ll_deinit(uart_ll_t *uct) {
    return -1;
}
/**
 * @brief 设置接收完成回调 仅GD32F407接收超时支持
 * @param  ult
 * @param  cb
 * @return int 0成功 -1失败
 * @note null
 */
int uart_ll_set_rx_done_cb(uart_ll_t *ult, uart_ll_rx_done_interrupt_cb_t cb) {
    ult->rx_done_cb = cb;
    return 0;
}
/**
 * @brief 发送指定长度的数据
 * @param  ult
 * @param  buf              发送的数据
 * @param  len_byte         数据的长度
 * @note null
 */
void uart_ll_putbuf(uart_ll_t *ult, uint8_t *buf, uint32_t len_byte) {
    ult->pTx = buf;
    ult->txbuf_len = len_byte;
    if (!ult->cfg_tx_interrupt) {
        for (uint32_t i = 0; i < ult->txbuf_len; i++) {
            while (uart_ll_transmit_status(ult) == 0)
                ;
            uart_ll_set_transmit_reg(ult, *ult->pTx++);
            while (uart_ll_transmit_complete(ult) == 0)
                ;
        }
        ult->txbuf_len = 0;
    } else {
        uart_ll_transmit_interrupt_enable(ult);
    }
}
/**
 * @brief 发送一个字节
 * @param  utt
 * @param  Sda              数据
 * @note null
 */
void uart_ll_write_byte(uart_ll_t *ult, uint16_t Sda) {
    while (uart_ll_transmit_status(ult) == 0)
        ;
    uart_ll_set_transmit_reg(ult, Sda);
    while (uart_ll_transmit_complete(ult) == 0)
        ;
}

/**
 * @brief UART发送中断使能
 * @param  usartx           USARTx
 * @note null
 */
void uart_ll_transmit_interrupt_enable(uart_ll_t *uct) {
#if defined(GD32F407) || defined(GD32F10X_HD)
    usart_interrupt_enable((uint32_t)uct->usartx, USART_INT_TBE);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    USART_ITConfig((void *)uct->usartx, USART_IT_TXE, ENABLE);
#elif defined(PY32F071xB)
    // SET_BIT(((USART_HandleTypeDef *)uct->usartx)->Instance->CR1, USART_CR1_TXEIE);
    __HAL_UART_ENABLE_IT(((UART_HandleTypeDef *)uct->usartx), UART_IT_TXE);
#endif
}
/**
 * @brief UART发送中断禁能
 * @param  usartx           USARTx
 * @note null
 */
void uart_ll_transmit_interrupt_disable(uart_ll_t *uct) {
#if defined(GD32F407) || defined(GD32F10X_HD)
    usart_interrupt_disable((uint32_t)uct->usartx, USART_INT_TBE);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    USART_ITConfig((void *)uct->usartx, USART_IT_TXE, DISABLE);
#elif defined(PY32F071xB)
    // CLEAR_BIT(((USART_HandleTypeDef *)uct->usartx)->Instance->CR1, USART_CR1_TXEIE);
    __HAL_UART_DISABLE_IT(((UART_HandleTypeDef *)uct->usartx), UART_IT_TXE);
#endif
}
/**
 * @brief 获取UART接受超时标志
 * @param  usartx           USARTx
 * @return uint8_t 0未置位 1置位
 * @note null
 */
uint8_t uart_ll_receive_time_out_status(uart_ll_t *uct) {
#if defined(GD32F407)
    return usart_interrupt_flag_get((uint32_t)uct->usartx, USART_INT_FLAG_RT);
#elif defined(GD32F10X_HD)
    // 不支持
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    // 不支持
#elif defined(PY32F071xB)
    // 不支持
#endif
    return 0;
}
/**
 * @brief 清除UART接受超时标志
 * @param  usartx           USARTx
 * @note null
 */
void uart_ll_receive_time_out_rststatus(uart_ll_t *uct) {
#if defined(GD32F407)
    usart_interrupt_flag_clear((uint32_t)uct->usartx, USART_INT_FLAG_RT);
#elif defined(GD32F10X_HD)
    // 不支持
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    // 不支持
#elif defined(PY32F071xB)
    // 不支持
#endif
}
/**
 * @brief 获取UART接收寄存器非空标志
 * @param  usartx           USARTx
 * @return uint8_t 0未置位 1置位
 * @note null
 */
uint8_t uart_ll_receive_interrupt_status(uart_ll_t *uct) {
#if defined(GD32F407) || defined(GD32F10X_HD)
    return usart_interrupt_flag_get((uint32_t)uct->usartx, USART_INT_FLAG_RBNE);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    return USART_GetITStatus((void *)uct->usartx, USART_IT_RXNE);
#elif defined(PY32F071xB)
    // return __HAL_USART_GET_FLAG(((USART_HandleTypeDef *)uct->usartx), USART_FLAG_RXNE);
    return __HAL_UART_GET_IT_SOURCE(((UART_HandleTypeDef *)uct->usartx), UART_IT_RXNE);
    // return READ_BIT(((USART_HandleTypeDef *)uct->usartx)->Instance->CR1, USART_CR1_RXNEIE);
#endif
    return 0;
}
/**
 * @brief 获取发送寄存器为空标志
 * @param  usartx           USARTx
 * @return uint8_t 0未置位 1置位
 * @note null
 */
uint8_t uart_ll_transmit_status(uart_ll_t *uct) {
#if defined(GD32F407) || defined(GD32F10X_HD)
    return usart_flag_get((uint32_t)uct->usartx, USART_FLAG_TBE);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    return USART_GetFlagStatus((void *)uct->usartx, USART_FLAG_TXE);
#elif defined(PY32F071xB)
    return __HAL_UART_GET_FLAG(((UART_HandleTypeDef *)uct->usartx), UART_FLAG_TXE);
#endif
    return 0;
}
/**
 * @brief 获取发送完成标志
 * @param  usartx           USARTx
 * @return uint8_t 0未置位 1置位
 * @note null
 */
uint8_t uart_ll_transmit_complete(uart_ll_t *uct) {
#if defined(GD32F407) || defined(GD32F10X_HD)
    return usart_flag_get((uint32_t)uct->usartx, USART_FLAG_TC);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    return USART_GetFlagStatus((void *)uct->usartx, USART_FLAG_TC);
#elif defined(PY32F071xB)
    return __HAL_UART_GET_FLAG(((UART_HandleTypeDef *)uct->usartx), UART_FLAG_TC);
#endif
    return 0;
}
/**
 * @brief 获取UART发送寄存器为空标志
 * @param  usartx           USARTx
 * @return uint8_t 0未置位 1置位
 * @note null
 */
uint8_t uart_ll_transmit_interrupt_status(uart_ll_t *uct) {
#if defined(GD32F407) || defined(GD32F10X_HD)
    return usart_interrupt_flag_get((uint32_t)uct->usartx, USART_INT_FLAG_TBE);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    return USART_GetITStatus((void *)uct->usartx, USART_IT_TXE);
#elif defined(PY32F071xB)
    return __HAL_UART_GET_IT_SOURCE(((UART_HandleTypeDef *)uct->usartx), UART_IT_TXE);
#endif
    return 0;
}
/**
 * @brief 获取UART接收寄存器
 * @param  usartx           USARTx
 * @return uint16_t 数据
 * @note null
 */
uint16_t uart_ll_get_receive_reg(uart_ll_t *uct) {
#if defined(GD32F407) || defined(GD32F10X_HD)
    return usart_data_receive((uint32_t)uct->usartx);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    return USART_ReceiveData((void *)uct->usartx);
#elif defined(PY32F071xB)
    return ((UART_HandleTypeDef *)uct->usartx)->Instance->DR;
#endif
    return 0;
}
/**
 * @brief 写UART发送寄存器
 * @param  usartx           USARTx
 * @param  data             发送的数据
 * @note null
 */
void uart_ll_set_transmit_reg(uart_ll_t *uct, uint16_t data) {
#if defined(GD32F407) || defined(GD32F10X_HD)
    usart_data_transmit((uint32_t)uct->usartx, data);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    USART_SendData((void *)uct->usartx, data);
#elif defined(PY32F071xB)
    ((UART_HandleTypeDef *)uct->usartx)->Instance->DR = data & 0xff;
#endif
}


/**********************************Private Functions*******************************/

static int gd32_uart_init(uart_ll_t *uct) {
#if defined(GD32F407) || defined(GD32F10X_HD)
    // clang-format off
    #if defined(GD32F407)
    gpio_ll_t gpio_cfg;
    uint32_t af_num;
    switch(uct->usartx) {
        case USART0:
        case USART1:
        case USART2: af_num = GPIO_AF_7; break;
        case UART3:
        case UART4:
        case USART5:
        case UART6:
        case UART7: af_num = GPIO_AF_8; break;
    }
    if (gpio_ll_init(&gpio_cfg, uct->port_tx, uct->pin_tx, GPIO_LL_MODE_AF, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_NO, GPIO_LL_SPEED_HIGH, af_num) < 0) {
        return -1;
    }
    if (gpio_ll_init(&gpio_cfg, uct->port_rx, uct->pin_rx, GPIO_LL_MODE_AF, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_NO, GPIO_LL_SPEED_HIGH, af_num) < 0) {
        return -1;
    }
    #elif defined(GD32F10X_HD)
    gpio_ll_t gpio_cfg;
    if (gpio_ll_init(&gpio_cfg, uct->port_tx, uct->pin_tx, GPIO_LL_MODE_AF, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_NO, GPIO_LL_SPEED_HIGH, 0) < 0) {
        return -1;
    }
    if (gpio_ll_init(&gpio_cfg, uct->port_rx, uct->pin_rx, GPIO_MODE_IN_FLOATING, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_NO, GPIO_LL_SPEED_HIGH, 0) < 0) {
        return -1;
    }
    #endif

    switch (uct->usartx) {
        case USART0: rcu_periph_clock_enable(RCU_USART0); break;
        case USART1: rcu_periph_clock_enable(RCU_USART1); break;
        case USART2: rcu_periph_clock_enable(RCU_USART2); break;
        case UART3: rcu_periph_clock_enable(RCU_UART3); break;
        case UART4: rcu_periph_clock_enable(RCU_UART4); break;
    #if defined(GD32F407)
        case USART5: rcu_periph_clock_enable(RCU_USART5); break;
        case UART6: rcu_periph_clock_enable(RCU_UART6); break;
        case UART7: rcu_periph_clock_enable(RCU_UART7); break;
    #endif
        default: return -1;
    }
    usart_deinit(uct->usartx);
    usart_baudrate_set(uct->usartx, uct->baudrate);
    switch (uct->uart_ll_data_bits) {
        case UART_LL_DATA_BIT_8: usart_word_length_set(uct->usartx, USART_WL_8BIT); break;
        case UART_LL_DATA_BIT_9: usart_word_length_set(uct->usartx, USART_WL_9BIT); break;
        default: return -1;
    }
    switch (uct->uart_ll_stop_bits) {
        case UART_LL_STOP_BIT_1: usart_stop_bit_set(uct->usartx, USART_STB_1BIT); break;
        case UART_LL_STOP_BIT_0_5: usart_stop_bit_set(uct->usartx, USART_STB_0_5BIT); break;
        case UART_LL_STOP_BIT_2: usart_stop_bit_set(uct->usartx, USART_STB_2BIT); break;
        case UART_LL_STOP_BIT_1_5: usart_stop_bit_set(uct->usartx, USART_STB_1_5BIT); break;
        default: return -1;
    }
    switch (uct->uart_ll_parity) {
        case UART_LL_PARITY_NONE: usart_parity_config(uct->usartx, USART_PM_NONE); break;
        case UART_LL_PARITY_EVEN: usart_parity_config(uct->usartx, USART_PM_EVEN); break;
        case UART_LL_PARITY_ODD: usart_parity_config(uct->usartx, USART_PM_ODD); break;
        default: return -1;
    }
    usart_hardware_flow_rts_config(uct->usartx, USART_RTS_DISABLE);
    usart_hardware_flow_cts_config(uct->usartx, USART_CTS_DISABLE);
    usart_receive_config(uct->usartx, USART_RECEIVE_ENABLE);
    usart_transmit_config(uct->usartx, USART_TRANSMIT_ENABLE);
    usart_interrupt_enable(uct->usartx, USART_INT_RBNE);
    usart_enable(uct->usartx);
    #if defined(GD32F407)
    if(uct->gd32usart_receive_overtime) {
        usart_receiver_timeout_threshold_config(uct->usartx, uct->overtime_ms * uct->baudrate / 1000);
        usart_interrupt_enable(uct->usartx, USART_INT_RT);
    }
    #endif
    // 开启中断前注册串口句柄
    switch (uct->usartx) {
        case (uint32_t)USART0: uart_handle[0] = uct; break;
        case (uint32_t)USART1: uart_handle[1] = uct; break;
        case (uint32_t)USART2: uart_handle[2] = uct; break;
        case (uint32_t)UART3: uart_handle[3] = uct; break;
        case (uint32_t)UART4: uart_handle[4] = uct; break;
    #if defined(GD32F407)
        case (uint32_t)USART5: uart_handle[5] = uct; break;
    #endif
        default: return -1;
    }
    switch (uct->usartx) {
        case USART0: nvic_irq_enable(USART0_IRQn, uct->cfg_interrupt_priority, 0); break;
        case USART1: nvic_irq_enable(USART1_IRQn, uct->cfg_interrupt_priority, 0); break;
        case USART2: nvic_irq_enable(USART2_IRQn, uct->cfg_interrupt_priority, 0); break;
        case UART3: nvic_irq_enable(UART3_IRQn, uct->cfg_interrupt_priority, 0); break;
        case UART4: nvic_irq_enable(UART4_IRQn, uct->cfg_interrupt_priority, 0); break;
    #if defined(GD32F407)
        case USART5: nvic_irq_enable(USART5_IRQn, uct->cfg_interrupt_priority, 0); break;
    #endif
        // case UART6: nvic_irq_enable(UART6_IRQn, uct->cfg_interrupt_priority, 0); break;
        // case UART7: nvic_irq_enable(UART7_IRQn, uct->cfg_interrupt_priority, 0); break;
        default: return -1;
    }
    // clang-format on
    return 0;
#endif
    return -1;
}

static int stm32_uart_init(uart_ll_t *uct) {
#if defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    // clang-format off
    #if defined(STM32F40_41xxx)
        uint32_t af_num;
        uint32_t af_source;
        switch(uct->usartx) {
            case (uint32_t)USART1: af_num = GPIO_AF_USART1; break;
            case (uint32_t)USART2: af_num = GPIO_AF_USART2; break;
            case (uint32_t)USART3: af_num = GPIO_AF_USART3; break;
            case (uint32_t)UART4: af_num = GPIO_AF_UART4; break;
            case (uint32_t)UART5: af_num = GPIO_AF_UART5; break;
            case (uint32_t)USART6: af_num = GPIO_AF_USART6; break;
            // case (uint32_t)UART7: af_num = GPIO_AF_UART7; break;
            // case (uint32_t)UART8:  af_num = GPIO_AF_UART8; break;
            default: return -1;
        }
        gpio_ll_t gpio_cfg;
        gpio_ll_init(&gpio_cfg, uct->port_tx, uct->pin_tx, GPIO_LL_MODE_AF, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_UP, GPIO_LL_SPEED_HIGH, af_num);
        gpio_ll_init(&gpio_cfg, uct->port_rx, uct->pin_rx, GPIO_LL_MODE_AF, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_UP, GPIO_LL_SPEED_HIGH, af_num);
        // 配置串口
        switch (uct->usartx) {
        case (uint32_t)USART1: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); break;
        case (uint32_t)USART2: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); break;
        case (uint32_t)USART3: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); break;
        case (uint32_t)UART4: RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); break;
        case (uint32_t)UART5: RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); break;
        case (uint32_t)USART6: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); break;
        // case (uint32_t)UART7: RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART7, ENABLE); break;
        // case (uint32_t)UART8: RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART8, ENABLE); break;
        default: return -1;
        }
        USART_DeInit((void *)uct->usartx);
        USART_InitTypeDef uart_cfg;
        uart_cfg.USART_BaudRate = uct->baudrate;
        uart_cfg.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        uart_cfg.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        
        switch (uct->uart_ll_data_bits) {
            case UART_LL_DATA_BIT_8: uart_cfg.USART_WordLength = USART_WordLength_8b; break;
            case UART_LL_DATA_BIT_9: uart_cfg.USART_WordLength = USART_WordLength_9b; break;
            default: return -1;
        }
        switch (uct->uart_ll_stop_bits) {
            case UART_LL_STOP_BIT_1: uart_cfg.USART_StopBits = USART_StopBits_1; break;
            case UART_LL_STOP_BIT_0_5: uart_cfg.USART_StopBits = USART_StopBits_0_5; break;
            case UART_LL_STOP_BIT_2: uart_cfg.USART_StopBits = USART_StopBits_2; break;
            case UART_LL_STOP_BIT_1_5: uart_cfg.USART_StopBits = USART_StopBits_1_5; break;
            default: return -1;
        }
        switch (uct->uart_ll_parity) {
            case UART_LL_PARITY_NONE: uart_cfg.USART_Parity = USART_Parity_No; break;
            case UART_LL_PARITY_EVEN: uart_cfg.USART_Parity = USART_Parity_Even; break;
            case UART_LL_PARITY_ODD: uart_cfg.USART_Parity = USART_Parity_Odd; break;
            default: return -1;
        }
        USART_Init((void *)uct->usartx, &uart_cfg);
        USART_Cmd((void *)uct->usartx, ENABLE);
        USART_ITConfig((void *)uct->usartx, USART_IT_RXNE, ENABLE);
        // 开启中断前注册串口句柄
        switch (uct->usartx) {
        case (uint32_t)USART1: uart_handle[0] = uct; break;
        case (uint32_t)USART2: uart_handle[1] = uct; break;
        case (uint32_t)USART3: uart_handle[2] = uct; break;
        case (uint32_t)UART4: uart_handle[3] = uct; break;
        case (uint32_t)UART5: uart_handle[4] = uct; break;
        case (uint32_t)USART6: uart_handle[5] = uct; break;
        // case (uint32_t)UART7: uart_handle[6] = uct; break;
        // case (uint32_t)UART8: uart_handle[7] = uct; break;
        default: return -1;
        }
        // 配置中断
        NVIC_InitTypeDef nvic_cfg;
        nvic_cfg.NVIC_IRQChannelPreemptionPriority = uct->cfg_interrupt_priority;
        nvic_cfg.NVIC_IRQChannelSubPriority = 0;
        nvic_cfg.NVIC_IRQChannelCmd = ENABLE;
        switch (uct->usartx) {
            case (uint32_t)USART1: nvic_cfg.NVIC_IRQChannel = USART1_IRQn; break;
            case (uint32_t)USART2: nvic_cfg.NVIC_IRQChannel = USART2_IRQn; break;
            case (uint32_t)USART3: nvic_cfg.NVIC_IRQChannel = USART3_IRQn; break;
            case (uint32_t)UART4: nvic_cfg.NVIC_IRQChannel = UART4_IRQn; break;
            case (uint32_t)UART5: nvic_cfg.NVIC_IRQChannel = UART5_IRQn; break;
            case (uint32_t)USART6: nvic_cfg.NVIC_IRQChannel = USART6_IRQn; break;
            // case (uint32_t)UART7: nvic_cfg.NVIC_IRQChannel = UART7_IRQn; break;
            // case (uint32_t)UART8: nvic_cfg.NVIC_IRQChannel = UART8_IRQn; break;
            default: return -1;
        }
        NVIC_Init(&nvic_cfg);
        return 0;
    #endif
    #if defined(STM32F10X_HD)
        gpio_ll_t gpio_cfg;
        gpio_ll_init(&gpio_cfg, uct->port_tx, uct->pin_tx, GPIO_LL_MODE_AF, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_NO, GPIO_LL_SPEED_HIGH, 0);
        gpio_ll_init(&gpio_cfg, uct->port_rx, uct->pin_rx, GPIO_LL_MODE_INPUT, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_NO, GPIO_LL_SPEED_HIGH, 0);
        // 配置串口
        switch (uct->usartx) {
        case (uint32_t)USART1: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); break;
        case (uint32_t)USART2: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); break;
        case (uint32_t)USART3: RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); break;
        case (uint32_t)UART4: RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); break;
        case (uint32_t)UART5: RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); break;
        #if defined(STM32F40_41xxx)
        case (uint32_t)UART6: RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART6, ENABLE); break;
        case (uint32_t)UART7: RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART7, ENABLE); break;
        case (uint32_t)UART8: RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART8, ENABLE); break;
        #endif
        default: return -1;
        }
        USART_DeInit((void *)uct->usartx);
        USART_InitTypeDef uart_cfg;
        uart_cfg.USART_BaudRate = uct->baudrate;
        uart_cfg.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        uart_cfg.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        
        switch (uct->uart_ll_data_bits) {
            case UART_LL_DATA_BIT_8: uart_cfg.USART_WordLength = USART_WordLength_8b; break;
            case UART_LL_DATA_BIT_9: uart_cfg.USART_WordLength = USART_WordLength_9b; break;
            default: return -1;
        }
        switch (uct->uart_ll_stop_bits) {
            case UART_LL_STOP_BIT_1: uart_cfg.USART_StopBits = USART_StopBits_1; break;
            case UART_LL_STOP_BIT_0_5: uart_cfg.USART_StopBits = USART_StopBits_0_5; break;
            case UART_LL_STOP_BIT_2: uart_cfg.USART_StopBits = USART_StopBits_2; break;
            case UART_LL_STOP_BIT_1_5: uart_cfg.USART_StopBits = USART_StopBits_1_5; break;
            default: return -1;
        }
        switch (uct->uart_ll_parity) {
            case UART_LL_PARITY_NONE: uart_cfg.USART_Parity = USART_Parity_No; break;
            case UART_LL_PARITY_EVEN: uart_cfg.USART_Parity = USART_Parity_Even; break;
            case UART_LL_PARITY_ODD: uart_cfg.USART_Parity = USART_Parity_Odd; break;
            default: return -1;
        }
        USART_Init((void *)uct->usartx, &uart_cfg);
        USART_Cmd((void *)uct->usartx, ENABLE);
        USART_ITConfig((void *)uct->usartx, USART_IT_RXNE, ENABLE);
        // 开启中断前注册串口句柄
        switch (uct->usartx) {
        case (uint32_t)USART1: uart_handle[0] = uct; break;
        case (uint32_t)USART2: uart_handle[1] = uct; break;
        case (uint32_t)USART3: uart_handle[2] = uct; break;
        case (uint32_t)UART4: uart_handle[3] = uct; break;
        case (uint32_t)UART5: uart_handle[4] = uct; break;
        default: return -1;
        }
        // 配置中断
        NVIC_InitTypeDef nvic_cfg;
        nvic_cfg.NVIC_IRQChannelPreemptionPriority = uct->cfg_interrupt_priority;
        nvic_cfg.NVIC_IRQChannelSubPriority = 0;
        nvic_cfg.NVIC_IRQChannelCmd = ENABLE;
        switch (uct->usartx) {
            case (uint32_t)USART1: nvic_cfg.NVIC_IRQChannel = USART1_IRQn; break;
            case (uint32_t)USART2: nvic_cfg.NVIC_IRQChannel = USART2_IRQn; break;
            case (uint32_t)USART3: nvic_cfg.NVIC_IRQChannel = USART3_IRQn; break;
            case (uint32_t)UART4: nvic_cfg.NVIC_IRQChannel = UART4_IRQn; break;
            case (uint32_t)UART5: nvic_cfg.NVIC_IRQChannel = UART5_IRQn; break;
            default: return -1;
        }
        NVIC_Init(&nvic_cfg);
        return 0;
    #endif
    // clang-format on
#endif
    return -1;
}

static int py32_uart_init(uart_ll_t *uct) {
#if defined(PY32F071xB)
    uint32_t af_tx = 0, af_rx = 0, uart_n;
    // clang-format off
    // 选择复用 反人类的设计
    switch (uct->port_tx) {
    case (uint32_t)GPIOA:
        switch (uct->pin_tx) {
        case GPIO_PIN_0: af_tx = GPIO_AF4_USART4; break;
        case GPIO_PIN_2: af_tx = GPIO_AF1_USART2; break;
        case GPIO_PIN_4: af_tx = GPIO_AF9_USART2; break;
        case GPIO_PIN_5: af_tx = GPIO_AF10_USART3; break;
        case GPIO_PIN_8: af_tx = GPIO_AF10_USART1; break;
        case GPIO_PIN_9: af_tx = GPIO_AF1_USART1; break;
        case GPIO_PIN_14: af_tx = ((UART_HandleTypeDef *)uct->usartx)->Instance == USART2 ? GPIO_AF1_USART2 : GPIO_AF9_USART1; break;
        default: return -1;
        }
        break;
    case (uint32_t)GPIOB:
        switch (uct->pin_tx) {
        case GPIO_PIN_2: af_tx = GPIO_AF10_USART3; break;
        case GPIO_PIN_5: af_tx = GPIO_AF13_USRAT1; break;
        case GPIO_PIN_6: af_tx = GPIO_AF0_USART1; break;
        case GPIO_PIN_8: af_tx = ((UART_HandleTypeDef *)uct->usartx)->Instance == USART1 ? GPIO_AF9_USART1 : GPIO_AF10_USART3; break;
        case GPIO_PIN_10: af_tx = GPIO_AF4_USART3; break;
        default: return -1;
        }
        break;
    case (uint32_t)GPIOC:
        switch (uct->pin_tx) {
        case GPIO_PIN_2: af_tx = GPIO_AF9_USART3; break;
        case GPIO_PIN_3: af_tx = GPIO_AF10_USART3; break;
        case GPIO_PIN_4: af_tx = ((UART_HandleTypeDef *)uct->usartx)->Instance == USART3 ? GPIO_AF1_USART3 : GPIO_AF9_USART1; break;
        case GPIO_PIN_7: af_tx = GPIO_AF10_USART4; break;
        case GPIO_PIN_10: af_tx = ((UART_HandleTypeDef *)uct->usartx)->Instance == USART4 ? GPIO_AF0_USART4 : GPIO_AF1_USART3; break;
        default: return -1;
        }
        break;
    case (uint32_t)GPIOF:
        switch (uct->pin_tx) {
        case GPIO_PIN_0: af_tx = GPIO_AF9_USART2; break;
        default: return -1;
        }
        break;
    default: return -1;
    }

    switch (uct->port_rx) {
    case (uint32_t)GPIOA:
        switch (uct->pin_rx) {
        case GPIO_PIN_1: af_rx = GPIO_AF4_USART4; break;
        case GPIO_PIN_3: af_rx = GPIO_AF1_USART2; break;
        case GPIO_PIN_10: af_rx = GPIO_AF1_USART1; break;
        case GPIO_PIN_13: af_rx = GPIO_AF9_USART1; break;
        case GPIO_PIN_15: af_rx = GPIO_AF1_USART2; break;
        default: return -1;
        }
        break;
    case (uint32_t)GPIOB:
        switch (uct->pin_rx) {
        case GPIO_PIN_0: af_rx = GPIO_AF10_USART3; break;
        case GPIO_PIN_7: af_rx = GPIO_AF0_USART1; break;
        case GPIO_PIN_9: af_rx = ((UART_HandleTypeDef *)uct->usartx)->Instance == USART1 ? GPIO_AF9_USART1 : GPIO_AF10_USART3; break;
        case GPIO_PIN_11: af_rx = GPIO_AF4_USART3; break;
        default: return -1;
        }
        break;
    case (uint32_t)GPIOC:
        switch (uct->pin_rx) {
        case GPIO_PIN_2: af_rx = GPIO_AF10_USART3; break;
        case GPIO_PIN_3: af_rx = GPIO_AF9_USART3; break;
        case GPIO_PIN_5: af_rx = ((UART_HandleTypeDef *)uct->usartx)->Instance == USART3 ? GPIO_AF1_USART3 : GPIO_AF9_USART1; break;
        case GPIO_PIN_6: af_rx = GPIO_AF10_USART4; break;
        case GPIO_PIN_11: af_rx = ((UART_HandleTypeDef *)uct->usartx)->Instance == USART4 ? GPIO_AF0_USART4 : GPIO_AF1_USART3; break;
        default: return -1;
        }
        break;
    case (uint32_t)GPIOF:
        af_rx = GPIO_AF9_USART2;
        break;
    default: return -1;
    }
    gpio_ll_t gpio_cfg;
    gpio_ll_init(&gpio_cfg, uct->port_tx, uct->pin_tx, GPIO_LL_MODE_AF, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_UP, GPIO_LL_SPEED_HIGH, af_tx);
    gpio_ll_init(&gpio_cfg, uct->port_rx, uct->pin_rx, GPIO_LL_MODE_AF, GPIO_LL_OTYPE_PP, GPIO_LL_PULL_UP, GPIO_LL_SPEED_HIGH, af_rx);

    switch ((uint32_t) ( ((UART_HandleTypeDef *)uct->usartx)->Instance )) {
    case (uint32_t)USART1: __HAL_RCC_USART1_CLK_ENABLE(); uart_n = 0; break;
    case (uint32_t)USART2: __HAL_RCC_USART2_CLK_ENABLE(); uart_n = 1; break;
    case (uint32_t)USART3: __HAL_RCC_USART3_CLK_ENABLE(); uart_n = 2; break;
    case (uint32_t)USART4: __HAL_RCC_USART4_CLK_ENABLE(); uart_n = 3; break;
    default: return -1;
    }

    UART_HandleTypeDef *uart_h = (void *)uct->usartx;
    uart_h->Init.BaudRate = uct->baudrate;
    switch (uct->uart_ll_data_bits) {
    case UART_LL_DATA_BIT_8: uart_h->Init.WordLength = UART_WORDLENGTH_8B; break;
    case UART_LL_DATA_BIT_9: uart_h->Init.WordLength = UART_WORDLENGTH_9B; break;
    default: return -1;
    }
    switch (uct->uart_ll_stop_bits) {
    case UART_LL_STOP_BIT_1: uart_h->Init.StopBits = UART_STOPBITS_1; break;
    case UART_LL_STOP_BIT_0_5: uart_h->Init.StopBits = UART_STOPBITS_0_5; break;
    case UART_LL_STOP_BIT_2: uart_h->Init.StopBits = UART_STOPBITS_2; break;
    case UART_LL_STOP_BIT_1_5: uart_h->Init.StopBits = UART_STOPBITS_1_5; break;
    default: return -1;
    }
    switch (uct->uart_ll_parity) {
    case UART_LL_PARITY_NONE: uart_h->Init.Parity = UART_PARITY_NONE; break;
    case UART_LL_PARITY_EVEN: uart_h->Init.Parity = UART_PARITY_EVEN; break;
    case UART_LL_PARITY_ODD: uart_h->Init.Parity = UART_PARITY_ODD; break;
    default: return -1;
    }
    uart_h->Init.HwFlowCtl = UART_HWCONTROL_NONE;
    uart_h->Init.Mode = UART_MODE_TX_RX;
    uart_h->Init.OverSampling = UART_OVERSAMPLING_16;
    uart_h->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    
    switch ((uint32_t) ( ((UART_HandleTypeDef *)(uct->usartx))->Instance )) {
    case (uint32_t)USART1: uart_handle[0] = uct; break;
    case (uint32_t)USART2: uart_handle[1] = uct; break;
    case (uint32_t)USART3: uart_handle[2] = uct; break;
    case (uint32_t)USART4: uart_handle[3] = uct; break;
    default: return -1;
    }
    HAL_UART_Init((UART_HandleTypeDef *)(uct->usartx));
    __HAL_UART_ENABLE_IT(((UART_HandleTypeDef *)uct->usartx), UART_IT_RXNE);
    switch ((uint32_t) ( ((UART_HandleTypeDef *)uct->usartx)->Instance )) {
    case (uint32_t)USART1:
        NVIC_SetPriority(USART1_IRQn, uct->cfg_interrupt_priority);
        NVIC_EnableIRQ(USART1_IRQn);
        break;
    case (uint32_t)USART2:
        NVIC_SetPriority(USART2_IRQn, uct->cfg_interrupt_priority);
        NVIC_EnableIRQ(USART2_IRQn);
        break;
    case (uint32_t)USART3:
    case (uint32_t)USART4:
        NVIC_SetPriority(USART3_4_IRQn, uct->cfg_interrupt_priority);
        NVIC_EnableIRQ(USART3_4_IRQn);
        break;
    default: return -1;
    }
// clang-format on
#endif
    return -1;
}

static inline void uart_ll_handle(uart_ll_t *ult) {
    // 接收数据
    if (uart_ll_receive_interrupt_status(ult) != 0) {
        uint16_t data = uart_ll_get_receive_reg(ult);
        if (ult->rx_cb) {
            ult->rx_cb(ult, data);
        }
    }
    // 发送中断
    if (ult->cfg_tx_interrupt) {
        if (uart_ll_transmit_interrupt_status(ult) != 0) {
            uart_ll_set_transmit_reg(ult, *ult->pTx++);
            ult->txbuf_len--;
            if (ult->txbuf_len <= 0) {
                uart_ll_transmit_interrupt_disable(ult);
            }
        }
    }
#if defined(GD32F407)
    // GD32F4 超时中断
    if (uart_ll_receive_time_out_status(ult) != 0) {
        // 接受完成
        uart_ll_receive_time_out_rststatus(ult);
        if (ult->gd32usart_receive_overtime) {
            if (ult->rx_done_cb) {
                ult->rx_done_cb(ult);
            }
        }
    }
#endif
}

// clang-format off
#if HAL_LL_UART
// 中断服务
#if defined(GD32F407) || defined(GD32F10X_HD)
    void USART0_IRQHandler(void) {
        uart_ll_handle(uart_handle[0]);
    }
    void USART1_IRQHandler(void) {
        uart_ll_handle(uart_handle[1]);
    }
    void USART2_IRQHandler(void) {
        uart_ll_handle(uart_handle[2]);
    }
    void UART3_IRQHandler(void) {
        uart_ll_handle(uart_handle[3]);
    }
    void UART4_IRQHandler(void) {
        uart_ll_handle(uart_handle[4]);
    }
    #if defined(GD32F407)
    void USART5_IRQHandler(void) {
        uart_ll_handle(uart_handle[5]);
    }
    #endif
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    void USART1_IRQHandler(void) {
        uart_ll_handle(uart_handle[0]);
    }
    void USART2_IRQHandler(void) {
        uart_ll_handle(uart_handle[1]);
    }
    void USART3_IRQHandler(void) {
        uart_ll_handle(uart_handle[2]);
    }
    void UART4_IRQHandler(void) {
        uart_ll_handle(uart_handle[3]);
    }
    void UART5_IRQHandler(void) {
        uart_ll_handle(uart_handle[4]);
    }
    #if defined(STM32F40_41xxx)
    void USART6_IRQHandler(void) {
        uart_ll_handle(uart_handle[5]);
    }
    // void UART7_IRQHandler(void) {
    //     uart_ll_handle(uart_handle[6]);
    // }
    // void UART8_IRQHandler(void) {
    //     uart_ll_handle(uart_handle[7]);
    // }
    #endif
#elif defined(PY32F071xB)
    void USART1_IRQHandler(void) {
        uart_ll_handle(uart_handle[0]);
    }
    void USART2_IRQHandler(void) {
        uart_ll_handle(uart_handle[1]);
    }
    void USART3_4_IRQHandler(void) {
        if (uart_handle[2]) {
            uart_ll_handle(uart_handle[2]);
        }
        if (uart_handle[3]) {
            uart_ll_handle(uart_handle[3]);
        }
    }
#endif
#endif // HAL_LL_UART
// clang-format on
/* [] END OF FILE */
